/*
 * ResipSdp.cpp
 *
 *  Created on: 2015年9月9日
 *      Author: terry
 */

#include "ResipSdp.h"
#include <sstream>

using namespace resip;

const char* ResipSdp::SENDONLY = "sendonly";
const char* ResipSdp::RECVONLY = "recvonly";
const char* ResipSdp::SENDRECV = "sendrecv";
const char* ResipSdp::INACTIVE = "inactive";


ResipSdp::ResipSdp()
{
}

ResipSdp::~ResipSdp()
{
}

std::string ResipSdp::toString(const resip::SdpContents& sdp)
{
    const SdpContents::Session& session = sdp.session();
    std::ostringstream oss;
    session.encode(oss);
    std::string strSdp = oss.str();
    return strSdp;
}

std::string ResipSdp::getStreamModeText(const SdpSession::Medium& medium)
{
	if (medium.exists(SENDONLY))
	{
		return SENDONLY;
	}
	else if (medium.exists(RECVONLY))
	{
		return RECVONLY;
	}
	else if (medium.exists(INACTIVE))
	{
		return INACTIVE;
	}
	return SENDRECV;
}

int ResipSdp::getStreamMode(const SdpSession::Medium& medium)
{
	if (medium.exists(SENDONLY))
	{
		return RtpMedium::kSendonly;
	}
	else if (medium.exists(RECVONLY))
	{
		return RtpMedium::kRecvOnly;
	}
	else if (medium.exists(INACTIVE))
	{
		return RtpMedium::kInactive;
	}
	return RtpMedium::kSendRecv;
}

SdpSession::Connection ResipSdp::getConnection(const SdpSession::Medium& medium)
{
    typedef std::list< SdpSession::Connection > ConnectionList;

    const ConnectionList& connList = medium.getConnections();
	if (!connList.empty())
	{
		return connList.front();
	}

	{
		const ConnectionList& connList = medium.getMediumConnections();
		if (!connList.empty())
		{
			return connList.front();
		}
	}
	return SdpSession::Connection(resip::SdpContents::IP4, "127.0.0.1");
}

const SdpSession::Codec* ResipSdp::findCodec(const SdpSession::Medium& medium, const char* name)
{
	const SdpSession::Medium::CodecContainer& codecs = medium.codecs();
	SdpSession::Medium::CodecContainer::const_iterator it = codecs.begin();
	if ((name == NULL) || (strlen(name) == 0))
	{
		if (it != codecs.end())
		{
			return &(*it);
		}
	}
	else
	{
		for (; it != codecs.end(); ++ it)
		{
			if ((*it).getName() == name)
			{
				return &(*it);
			}
		}
	}
	return NULL;
}

const SdpSession::Codec* ResipSdp::findCodec(const SdpSession::Medium& medium, const char* name,
		const char* fmtp)
{
	const SdpSession::Medium::CodecContainer& codecs = medium.codecs();
	SdpSession::Medium::CodecContainer::const_iterator it = codecs.begin();
	if ((name == NULL) || (strlen(name) == 0))
	{
		if (it != codecs.end())
		{
			return &(*it);
		}
	}
	else
	{
		SdpSession::Medium::CodecContainer::const_iterator itFound = codecs.end();
		for (; it != codecs.end(); ++ it)
		{
			if ((*it).getName() == name)
			{
				itFound = it;

				const SdpSession::Codec& codec = *it;
                if (codec.parameters().find(fmtp) != -1)
                {
                    break;
                }
			}
		}

		if (itFound != codecs.end())
		{
			return &(*itFound);
		}
	}
	return NULL;
}

bool ResipSdp::parse(const SdpSession::Medium& medium, const char* codecName, RtpMedium& rtpMedium)
{
	const SdpSession::Codec* codec = findCodec(medium, codecName);
	return parse(medium, codec, rtpMedium);
}

bool ResipSdp::parse(const SdpSession::Medium& medium, const SdpSession::Codec* codec, RtpMedium& rtpMedium)
{
	if (!codec)
	{
		return false;
	}

    SdpSession::Connection connection = getConnection(medium);

	rtpMedium.name = medium.name().c_str();
	rtpMedium.ip = connection.getAddress().c_str();
	rtpMedium.port = medium.port();

	rtpMedium.mode = getStreamMode(medium);

	rtpMedium.codec = codec->getName().c_str();
	rtpMedium.payload = codec->payloadType();
	rtpMedium.clockRate = codec->getRate();

	rtpMedium.fmtp = codec->parameters().c_str();

	return true;
}

const SdpSession::Medium* ResipSdp::findMedium(const SdpSession& session, const char* name)
{
	const SdpSession::MediumContainer& mediums = session.media();
	SdpSession::MediumContainer::const_iterator it = mediums.begin();
	for (; it != mediums.end(); ++ it)
	{
		const SdpSession::Medium& medium = *it;
		if (medium.name() == name)
		{
			return &medium;
		}
	}
	return NULL;
}

resip::Data ResipSdp::getMediumIP(const SdpSession::Medium& medium)
{
	return getConnection(medium).getAddress();
}


